#ifndef BA_H
#define BA_H

#include <QThread>
#include "ComStruct.h"
#include <QTcpSocket>
#include <QList>
#include <QSemaphore>
#include "ModbusFactory.h"

class CBA : public QThread
{
	Q_OBJECT

public:
	CBA(QObject *pWgt, CModbusFactory* pModbusFactory, CBattStack* pStackMaster);
	~CBA();

public:
	void run();

	void setIPAndPort(const QString& strIP, ushort usPort);
	void enableAcquComInputReg(int iBAIndex);
	void setBAIndex(int iBAIndex);
	void enableAcquSglData(int iCellNum, int iTempNum);
	void setLinkageStrategy(int iLinkageStrategy);
	bool isEnableAcquComInputReg();
	int getBAIndex();
	quint16* getComInputReg();
	void enablePrintBAMsg(bool bPrint);

	int addBattBank(uchar uaModbusAddr, uchar uaModbusAddrBg);
	CBattBank* getBattBankByMaddr(uchar uaModbusAddr);
	CBattBank* getBattBankByMaddrBg(uchar uaModbusAddrBg, SAlarmParam** pAlarmParam);
	CBattStack* getStack();

	QString getIP();
	ushort getPort();

	int getBattBankSize();
	CBattBank* getBattBankByIndex(int iIndex);

	int getRegVal(quint16 usModbusAddr, quint16 usRegAddr, quint16& usVal);
	bool getBAConnectedState();

	// 转发 远程 设置命令
	int tranSetHoldReg2Slave(char* pDataBuf, int iLen, uchar uaAddrBg);
	int checkTranDatagram();
    // void setLinkageTrip(bool bLastLinkageTrip, bool& bLinkageTrip);
	
private:
	void printSendInfo(int iIndexStep, char* pSendBufData, int iLen);
	void printReceInfo(int iIndexStep, char* pSendBufData, int iLen);
	QString getMsgFromIndexStep(int iIndexStep);
	int requestSlaveBAStack();
	void adjustIndexStep(int& iIndexStep);
	int processStackHoldReg();
	int processBankHoldReg(CBattBank* pBattBank, int iIndex);
//	int processSetHoldReg(int iSetHoldRegStep, CBattBank* pBattBank, SAlarmParam* pAlarmParam);
	void readChangedBankHoldReg();

signals:
	void addLog(int iLogType, const QString& strLog);
	void notifyBAStateChanged(const QString& strBA, bool bConnected);

private slots:
	void disconnected();

private:
	// Tcp Socket
	QString m_strIP;                  // BA IP
	ushort m_usPort;                  // BA Port
	QTcpSocket* m_pTcpClient;
	bool m_bTcpConnected;

	bool m_bAcquSglDataEnable;        // 是否采集单体数据 
	bool m_bAcquComInputRegEnable;    // 是否采集通用输入寄存器
	quint16 m_usComInputRegVal[100];  // 通用输入寄存器 地址从 1 ~ 100
	int m_iBAIndex;                   // BA 索引号 Modbus 后台地址

	char* m_pDataBuf;                 // send and receive data buffer
	int m_iHasReadBytesNum;           // have read num

	CBattStack* m_pBattStack;         // 堆数据
	CBattStack* m_pBattStackMaster;   // 堆数据 主BA
	QList<CBattBank*>* m_pLstBatt;    // 电池组 
	QList<SAlarmParam*>* m_pLstSlaveParam; // 电池组参数读取	
	CModbusFactory* m_pModbusFactory; // Modbus工厂

	int m_iTryConnectBANum;           // 尝试连接BA计数
	bool m_bBAConnected;              // BA连接正常

	bool m_bPrintBAMsg;

	int m_iCellNum;                   // 采集单体数据时, 控制帧数 提高速度
	int m_iTempNum;

	QSemaphore* m_pSemaphore;         // 转发信号量
	uchar m_uaAddrBg;                 // 转发后台Modbus Addr         
	char* m_pTranDataBuf;             // 转发数据报文
	int m_iTranDataLen;               // 转发数据长度

	int m_iLinkageStrategy;           // 联动策略	
};

#endif // BA_H
